home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Moscow ML 1.42 / examples / lexyacc / Lexer.lex < prev    next >
Encoding:
Text File  |  1997-08-18  |  2.8 KB  |  79 lines  |  [TEXT/R*ch]

  1. {
  2.  open Lexing Parser;
  3.  
  4.  exception LexicalError of string * int * int (* (message, loc1, loc2) *)
  5.  
  6.  fun lexerError lexbuf s = 
  7.      raise LexicalError (s, getLexemeStart lexbuf, getLexemeEnd lexbuf);
  8.  
  9.  val commentStart = ref 0;  (* Start of outermost comment being scanned *)
  10.  
  11.  fun commentNotClosed lexbuf =
  12.      raise LexicalError ("Comment not terminated", 
  13.                          !commentStart, getLexemeEnd lexbuf);
  14.      
  15.  val commentDepth = ref 0;  (* Current comment nesting *)
  16.  
  17.  fun keyword s =
  18.      case s of
  19.          "let"          => LET
  20.        | "letrec"       => LETREC
  21.        | "in"           => IN
  22.        | "case"         => CASE
  23.        | "of"           => OF
  24.        | "if"           => IF
  25.        | "then"         => THEN
  26.        | "else"         => ELSE
  27.        | "pack"         => PACK
  28.        | "end"          => END
  29.        | _              => NAME s;
  30.  
  31.  }
  32.  
  33. rule Token = parse
  34.     [` ` `\t` `\n` `\r`]     { Token lexbuf }
  35.   | `~`?[`0`-`9`]+      { case Int.fromString (getLexeme lexbuf) of
  36.                                NONE   => lexerError lexbuf "internal error"
  37.                              | SOME i => INT i
  38.                         }  
  39.   | [`a`-`z``A`-`Z`][`a`-`z``A`-`Z``0`-`9`]*
  40.                         { keyword (getLexeme lexbuf) }
  41.   | "(*"                { commentStart := getLexemeStart lexbuf;
  42.                           commentDepth := 1; 
  43.                           SkipComment lexbuf; Token lexbuf }
  44.   | "->"                { DASHARROW }
  45.   | `=`                 { EQ }
  46.   | "~="                { NE }
  47.   | `>`                 { GT }
  48.   | `<`                 { LT }
  49.   | ">="                { GE }
  50.   | "<="                { LE }
  51.   | `+`                 { PLUS }                     
  52.   | `-`                 { MINUS }                     
  53.   | `*`                 { TIMES }                     
  54.   | `/`                 { DIV }                     
  55.   | `%`                 { MOD }                     
  56.   | `|`                 { BAR }                     
  57.   | `&`                 { AMPERSAND }                     
  58.   | `\\`                { LAMBDA }                     
  59.   | `(`                 { LPAR }
  60.   | `)`                 { RPAR }
  61.   | `{`                 { LBRACE }
  62.   | `}`                 { RBRACE }
  63.   | `;`                 { SEMI }
  64.   | `,`                 { COMMA }
  65.   | `.`                 { DOT }
  66.   | eof                 { EOF }
  67.   | _                   { lexerError lexbuf "Illegal symbol in input" }
  68.  
  69. and SkipComment = parse
  70.     "*)"                { commentDepth := !commentDepth - 1;  
  71.                           if !commentDepth = 0 then ()
  72.                           else SkipComment lexbuf 
  73.                         } 
  74.    | "(*"               { commentDepth := !commentDepth + 1; 
  75.                           SkipComment lexbuf }
  76.    | (eof | `\^Z`)      { commentNotClosed lexbuf }
  77.    | _                  { SkipComment lexbuf }
  78. ;
  79.